package com.manolo.server;

import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.google.gson.Gson;
import com.manolo.engine.Engine;
import com.manolo.event.entity.Card;
import com.manolo.event.GameStartEvent;
import com.manolo.event.HandCardEvent;
import com.manolo.engine.entity.Deck;
import com.manolo.server.dispatcher.ProcessCommunicationDispatcher;
import com.manolo.event.EventType;
import com.manolo.event.entity.Message;
import com.manolo.server.entity.Partner;
import com.manolo.server.entity.Game;
import com.manolo.server.entity.Player;
import com.manolo.server.event.ProcessEvent;
import com.manolo.server.event.ServerDataEvent;

public class Truco extends GameGenericCommunication {

	

	@Override
	public void onNewConnection(ServerDataEvent event) {
		addPlayer(event.getSocket());

		if (mapPlayer.size() > NUMBER_PLAYER_TO_START_GAME) { // refuse new
																// connections
			System.out.println("::::::::::::refuse player ::::::::::::");
			removePlayer(event.getSocket());
			refuseConnetion(event.getSocket());
		}
	}

	@Override
	public void onReceiveMessage(ServerDataEvent event) {
		processData(event.getSocket(), event.getData(), event.getNumberReader());

	}

	@Override
	public void onCloseConnetion(ServerDataEvent event) {
		removePlayer(event.getSocket());

	}

	/*public void gameStart() {
		// Wait 2 or 4 player to start of the game

		System.out.println("::::::::::::Start game::::::::::::");
		Deck deck = new Deck(1, 3, 4);
		// Shuffle the Deck
		deck.shuffleDeck();
		// Cut the deck at the position 2
		deck.cutDeck(22);

		ArrayList<List<Card>> allHands = deck.distributeCards();

		Map<Integer, Card> map = new HashMap<Integer, Card>();
		Iterator<Entry<SocketChannel, Player>> iterator = mapPlayer.entrySet()
				.iterator();

		int indexHand = 0;
		while (iterator.hasNext()) {
			Entry<SocketChannel, Player> entry = iterator.next();
			System.out.println("aa::::" + entry.getValue().getId());
			if (indexHand <= NUMBER_PLAYER_TO_START_GAME) {
				System.out.println("cc::::" + entry.getValue().getId());
				entry.getValue().getCards().addAll(allHands.get(indexHand));
			}
			indexHand++;
		}

		// Send cards to every players
		sendCardsAllPlayer();
		// System.out.println(Engine.getTheHandWinner(map,1));

	}*/
	
	public void gameStart()
	{
		Iterator<Entry<SocketChannel, Player>> iterator = mapPlayer.entrySet()
				.iterator();
		GameStartEvent evt;
		Gson gson = new Gson();
		Message msg = new Message();
		HandCardEvent cardEvent;
		Game newGame = new Game();
		
		Partner pair = new Partner();
		pair.setPlayerOne(iterator.next());
		pair.setPlayerTwo(iterator.next());
		
		Partner odd = new Partner();
		odd.setPlayerOne(iterator.next());
		odd.setPlayerTwo(iterator.next());
		
		newGame.setPairPlayers(pair);
		newGame.setOddPlayers(odd);
		
		
		//dispatch to pair player
		evt = new GameStartEvent();
		evt.setBottomPlayerName(pair.getPlayerOne().getValue().getName());
		evt.setLeftPlayerName(odd.getPlayerOne().getValue().getName());
		evt.setTopPlayerName(pair.getPlayerTwo().getValue().getName());
		evt.setRightPlayerName(odd.getPlayerTwo().getValue().getName());
		msg = new Message();
		msg.setEventType(EventType.GAME);
		msg.setMethod("startGame");
		msg.setEvent(gson.toJson(evt));
		addMessageToQueue(msg, pair.getPlayerOne().getKey());
		
		//dispatch to left player
		evt = new GameStartEvent();
		evt.setBottomPlayerName(odd.getPlayerOne().getValue().getName());
		evt.setLeftPlayerName(pair.getPlayerTwo().getValue().getName());
		evt.setTopPlayerName(odd.getPlayerTwo().getValue().getName());
		evt.setRightPlayerName(pair.getPlayerOne().getValue().getName());
		msg = new Message();
		msg.setEventType(EventType.GAME);
		msg.setMethod("startGame");
		msg.setEvent(gson.toJson(evt));
		addMessageToQueue(msg, odd.getPlayerOne().getKey());
		
		//dispatch to top player
		evt = new GameStartEvent();
		evt.setBottomPlayerName(pair.getPlayerTwo().getValue().getName());
		evt.setLeftPlayerName(odd.getPlayerTwo().getValue().getName());
		evt.setTopPlayerName(pair.getPlayerOne().getValue().getName());
		evt.setRightPlayerName(odd.getPlayerOne().getValue().getName());
		msg = new Message();
		msg.setEventType(EventType.GAME);
		msg.setMethod("startGame");
		msg.setEvent(gson.toJson(evt));
		addMessageToQueue(msg, pair.getPlayerTwo().getKey());
		
		//dispatch to right player
		evt = new GameStartEvent();
		evt.setBottomPlayerName(odd.getPlayerTwo().getValue().getName());
		evt.setLeftPlayerName(pair.getPlayerOne().getValue().getName());
		evt.setTopPlayerName(odd.getPlayerOne().getValue().getName());
		evt.setRightPlayerName(pair.getPlayerTwo().getValue().getName());
		msg = new Message();
		msg.setEventType(EventType.GAME);
		msg.setMethod("startGame");
		msg.setEvent(gson.toJson(evt));
		addMessageToQueue(msg, odd.getPlayerTwo().getKey());
		
		//create deck instance
		Deck deck = new Deck(1, 3, 4);
		// Shuffle the Deck
		deck.shuffleDeck();
		// Cut the deck at the position 2
		deck.cutDeck(22);
		
		
		ArrayList<List<Card>> allHands = deck.distributeCards();
		
		cardEvent = new HandCardEvent();
		cardEvent.setCards(allHands.get(0));
		msg = new Message();
		msg.setEventType(EventType.CARD);
		msg.setMethod("handCards");
		msg.setEvent(gson.toJson(cardEvent));
		addMessageToQueue(msg, pair.getPlayerOne().getKey());
		
		cardEvent = new HandCardEvent();
		cardEvent.setCards(allHands.get(1));
		msg = new Message();
		msg.setEventType(EventType.CARD);
		msg.setMethod("handCards");
		msg.setEvent(gson.toJson(cardEvent));
		addMessageToQueue(msg, pair.getPlayerTwo().getKey());
		
		cardEvent = new HandCardEvent();
		cardEvent.setCards(allHands.get(2));
		msg = new Message();
		msg.setEventType(EventType.CARD);
		msg.setMethod("handCards");
		msg.setEvent(gson.toJson(cardEvent));
		addMessageToQueue(msg, odd.getPlayerOne().getKey());
		
		cardEvent = new HandCardEvent();
		cardEvent.setCards(allHands.get(3));
		msg = new Message();
		msg.setEventType(EventType.CARD);
		msg.setMethod("handCards");
		msg.setEvent(gson.toJson(cardEvent));
		addMessageToQueue(msg, odd.getPlayerTwo().getKey());
			
		//}
	}
	
	@Override
	public void run() {
		ProcessEvent event;
		while (true) {
			// Wait for data to become available
			synchronized (queue) {
				while (queue.isEmpty()) {
					try {
						queue.wait();
					} catch (InterruptedException e) {
					}
				}
				event = (ProcessEvent) queue.remove(0);
				ProcessCommunicationDispatcher.getInstance()
						.dispatchSendeMessage(event);

			}
		}
	}
}
